package top.jacktgq.cas.account.v1;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class TestAccount {
	public static void main(String[] args) {
		Account.demo(new AccountSync(10000));
		Account.demo(new AccountCas(10000));
	}
}
class AccountCas implements Account {
	private AtomicInteger balance;
	
	public AccountCas(int balance) {
		this.balance = new AtomicInteger(balance);
	}

	@Override
	public Integer getBalance() {
		return balance.get();
	}

	@Override
	public void withdraw(int amount) {
		/*while(true) {
			//获取余额的最新值
			int prev = balance.get();
			//要修改的余额
			int next = prev - amount;
			//真正修改
			if(balance.compareAndSet(prev, next)) {
				break;
			}
		}*/
		//以上代码可以简化为
		balance.addAndGet(-amount);
	}
}

class AccountSync implements Account {
	private Integer balance;
	
	public AccountSync(Integer balance) {
		this.balance = balance;
	}

	@Override
	public Integer getBalance() {
		return this.balance;
	}

	@Override
	public synchronized void withdraw(int amount) {
		this.balance -= amount;
	}
}

interface Account {
	//获取余额
	Integer getBalance();
	
	//取款
	void withdraw(int amount);
	
	/**
	 * 方法内会启动1000个线程，每个线程做-10元的操作，
	 * 如果初始余额为10000元，那么正确的结果应当是0
	 */
	static void demo(Account account) {
		List<Thread> threadList = new ArrayList<Thread>();
		for(int i = 0; i < 1000; i++) {
			threadList.add(new Thread(() -> {
				account.withdraw(10);
			}));
		}
		
		long start = System.currentTimeMillis();
		
		threadList.forEach(Thread :: start);
		threadList.forEach(t -> {
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});
		long end = System.currentTimeMillis();
		System.out.println("balance:" + account.getBalance() + ",cost:" + (end - start) + " ms");
		
	}
}